package springcache

import (
	algo "SpringCache/cachealgorithm"
	"SpringCache/cachealgorithm/fifo"
	"SpringCache/cachealgorithm/lfu"
	"SpringCache/cachealgorithm/lru"
	twoqueues "SpringCache/cachealgorithm/twoqueue"
	"sync"
)

// 设计一个并发缓存
type cache struct {
	mu         sync.Mutex
	Cache      algo.CacheAlgorithm
	cacheBytes int64
	cacheType  string
}

// add 使用锁保证数据的一致性,底层调用lru的Add方法调整lru结构
func (c *cache) add(key string, value *ByteView) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if c.Cache == nil {
		switch c.cacheType {
		case "LFU":
			c.Cache = lfu.New(c.cacheBytes, nil)
		case "FIFO":
			c.Cache = fifo.New(c.cacheBytes, nil)
		case "TWO-QUEUES":
			c.Cache = twoqueues.New(c.cacheBytes, nil)
		default:
			c.Cache = lru.New(c.cacheBytes, nil)
		}
		// if lru.DefaultMaxBytes > c.cacheBytes {
		// 	c.Cache = lru.New(lru.DefaultMaxBytes, nil)
		// } else {
		// 	c.Cache = lru.New(c.cacheBytes, nil)
		// }
	}
	c.Cache.Add(key, value, value.Expire())
}

// get 加锁,调用底层的Get
func (c *cache) get(key string) (value *ByteView, ok bool) {
	c.mu.Lock()
	defer c.mu.Unlock()
	if c.Cache == nil {
		return
	}
	if v, ok := c.Cache.Get(key); ok {
		return v.(*ByteView), ok
	}
	return
}
